<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Helpers\Auth;
use App\Helpers\URL;
use App\Services\ProfileService;
use InvalidArgumentException;
use Riverside\Express\Application;
use Riverside\Express\Request;
use Riverside\Express\Response;

class ProfileController
{
    /**
     * Obtiene los campos necesarios para modificar una cuenta de usuario.
     */
    private function getProfileFields(): array
    {
        return ['photo', 'username', 'email', 'password', 'confirm_password'];
    }

    /**
     * Obtiene una instancia del servicio de perfiles.
     */
    private function profileService(Application $app): ProfileService
    {
        return new ProfileService($app);
    }

    /**
     * Muestra la vista para modificar la cuenta de un usuario.
     */
    public function edit(Request $req, Response $res): void
    {
        $validations = $values = $status = [];
        $success = $req->session['success'] ?? null;
        $error = $req->session['error'] ?? null;
        $event = $req->query[URL::getQueryEventName()] ?? null;
        $userAuth = $req->app->local(Auth::getVarname());

        foreach ($this->getProfileFields() as $field) {
            $validations[$field] = $req->session['validations'][$field] ?? null;
            $values[$field] = $req->session['values'][$field] ?? $userAuth[$field] ?? null;
            $status[$field] = isset($validations[$field]) ? 'error' : null;
        }

        foreach (['validations', 'values', 'success', 'error'] as $key) {
            unset($req->session[$key]);
        }

        $res->render('profile/edit', [
            'app' => $req->app,
            'validations' => $validations,
            'values' => $values,
            'status' => $status,
            'success' => $success,
            'error' => $error,
            'event' => $event,
        ]);
    }

    /**
     * Modifica la cuenta de un usuario.
     */
    public function update(Request $req, Response $res): void
    {
        $data = [];

        // Obtiene solo los campos necesarios de la petición.
        foreach ($this->getProfileFields() as $field) {
            $data[$field] = $req->body[$field] ?? null;
        }

        // Obtiene el id del usuario autenticado.
        $userAuthId = $req->app->local(Auth::getVarname())['id'];

        try {
            // Modifica la información de la cuenta del usuario autenticado.
            $this->profileService($req->app)->update($userAuthId, $data);
        } catch (InvalidArgumentException $e) {
            $gump = $req->app->local('gump');

            $req->session['validations'] = $gump->get_errors_array();
            $req->session['values'] = $data;
            $req->session['error'] = $e->getMessage();

            $res->redirect(URL::event('profile', 'profileUpdate'));
        }

        $req->session['success'] = 'Tu cuenta se ha modificado correctamente';

        $res->render('components/redirect', ['url' => URL::site('profile')]);
    }
}
